/**
 * Copyright (c) 2008 Johannes Tacskovics
 * 
 * Permission is hereby granted, free of charge, to any person
 * obtaining a copy of this software and associated documentation
 * files (the "Software"), to deal in the Software without
 * restriction, including without limitation the rights to use,
 * copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the
 * Software is furnished to do so, subject to the following conditions:
 * 
 * The above copyright notice and this permission notice shall be
 * included in all copies or substantial portions of the Software.
 *  
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
 * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
 * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
 * OTHER DEALINGS IN THE SOFTWARE.
 */

package ca.johannes.display {
	import flash.accessibility.AccessibilityImplementation;
	import flash.accessibility.AccessibilityProperties;
	import flash.display.DisplayObject;
	import flash.display.DisplayObjectContainer;
	import flash.display.Graphics;
	import flash.display.LoaderInfo;
	import flash.display.MovieClip;
	import flash.display.Scene;
	import flash.display.Sprite;
	import flash.display.Stage;
	import flash.events.Event;
	import flash.geom.Point;
	import flash.geom.Rectangle;
	import flash.geom.Transform;
	import flash.media.SoundTransform;
	import flash.text.TextSnapshot;
	import flash.ui.ContextMenu;
	
    //--------------------------------------
    //  Class description
    //--------------------------------------
	/**
	 * The GotoClip extends the base functionality found in the flash.display.MovieClip class.
	 * It recreates some of the functionality found in the ActionScript 2.0 version of the MovieClip.
	 * This class introduces the ability to call <code>gotoAndStop</code> or <code>gotoAndPlay</code> 
	 * and then set properties or call methods on children MovieClips immediately afterwards. For each 
	 * call to a child MovieClip it creates a proxy and applies the commands to the proxy. When the 
	 * Flash Player runtime has moved to the correct frame and all the display list children have been 
	 * drawn to the screen the proxy then applies the commands to the ready children. 
     *
     * @see flash.display.MovieClip
     *
     * @langversion 3.0
     * @playerversion Flash 9.0.124.0
	 */	
	public class GotoClip extends MovieClip {	
		
		/**
         * @private (protected)
         *
         * @langversion 3.0
         * @playerversion Flash 9.0.124.0
		 */
		protected var _isGoto:Boolean = false;
		/**
         * @private (protected)
         *
         * @langversion 3.0
         * @playerversion Flash 9.0.124.0
		 */
		protected var _movieClip:MovieClip;
		/**
         * @private (protected)
         *
         * @langversion 3.0
         * @playerversion Flash 9.0.124.0
		 */
		protected var isInherited:Boolean;
		/**
         * @private (protected)
         *
         * @langversion 3.0
         * @playerversion Flash 9.0.124.0
		 */		
		protected var gotoFrame:Object;
		/**
         * @private (protected)
         *
         * @langversion 3.0
         * @playerversion Flash 9.0.124.0
		 */
		protected var proxies:Array = new Array();
		
		/**
         * Creates a new GotoClip instance. It can be used to apply funtionality to 
         * a MovieClip through composition or inheritance. It can be set as the base
         * class for a library asset within a FLA file and inherit the funtionality,
         * or an instance of a MovieClip can be passed into the constructor.
         * 
         * @param target an optional parameter, using this will wrap the functionality around the target.
		 * @throws Error if an target is already a GotoClip.
         * @langversion 3.0
         * @playerversion Flash 9.0.124.0
		 */
		public function GotoClip(target:MovieClip = null) {
			if (target is GotoClip){
				throw new Error("Cannot set target as GotoClip");
			}
			
			if (target) {
				isInherited = false;
				_movieClip = target;
			} else {
				isInherited = true;
				_movieClip = this;
			}
		}
		/**
         * The MovieClip instance that the GotoClip functionality has been applied to.
         * If the class instance was instantiated by inheritance as a FLA library asset this 
         * getter returns the same instance. If a target MovieClip was passed into the
         * class constructor the reference to the target MovieClip is returned.
         *
         * @langversion 3.0
         * @playerversion Flash 9.0.124.0
		 */	
		public function get movieClip():MovieClip {
			return _movieClip;
		}
		/**
         * Changing from one frame to the next is not instantaneous, as such this getter returns a 
         * boolean describing the state of any <code>gotoAndPlay</code> or <code>gotoAndStop</code> 
         * call. <code>true</code> is returned if the MovieClip has received <code>gotoAndPlay</code> 
         * or <code>gotoAndStop</code> call and has not yet reached the destination frame. Otherwise 
         * <code>false</code> is returned. 
         *
         * @langversion 3.0
         * @playerversion Flash 9.0.124.0
		 */
		public function get isGoto():Boolean {
			return _isGoto;
		}
		/**
         * @private (protected)
         *
         * @langversion 3.0
         * @playerversion Flash 9.0.124.0
		 */
		protected function callProperty(methodName:String, ...args):* {			
			if (args[0] is Array){
				args = args[0];
			}
			
			var method:Function = (isInherited) ? super[methodName] as Function : movieClip[methodName] as Function;
			return method.apply(movieClip, args);
		}		
		/**
         * @private
         *
         * @langversion 3.0
         * @playerversion Flash 9.0.124.0
		 */
		super_namespace function callProperty(methodName:String, ...args):* {			
			if (args[0] is Array){
				args = args[0];
			}
			
			var method:Function;
			if (isInherited) {
				method = super[methodName] as Function;
			} else if (movieClip is GotoProxy){
				method = movieClip.super_namespace::[methodName] as Function;
			} else {
				method = movieClip[methodName] as Function;
			}
			return method.apply(movieClip, args);
		}
		/**
         * @private (protected)
         *
         * @langversion 3.0
         * @playerversion Flash 9.0.124.0
		 */
		protected function getProperty(name:String):* {
			if (isInherited){
				return super[name];
			} else {
				return movieClip[name];
			}
		}
		/**
         * @private (protected)
         *
         * @langversion 3.0
         * @playerversion Flash 9.0.124.0
		 */
		protected function setProperty(name:String, value:*):void {
			if (isInherited){
				super[name] = value;
			} else {
				movieClip[name] = value;
			}
		}
		/**
         * @private (protected)
         *
         * @langversion 3.0
         * @playerversion Flash 9.0.124.0
		 */
		protected function createGotoProxy(methodName:String, index:*): MovieClip {
			var gotoClip:GotoClip;
			var len:int = proxies.length;
			for (var i:int = 0; i<len; i++){
				var gotoProxyAndRequest:GotoProxyAndRequest = proxies[i];
				if (methodName == gotoProxyAndRequest.methodName && index == gotoProxyAndRequest.index){
					gotoClip = gotoProxyAndRequest.gotoClip;
					break;
				}
			}
			if (!gotoClip){
				var gotoProxy:GotoProxy = new GotoProxy();
				gotoClip = new GotoClip(gotoProxy);
				proxies.push(new GotoProxyAndRequest(gotoClip, methodName, index));
			}
			return gotoClip;
		}
		/**
         * @private (protected)
         *
         * @langversion 3.0
         * @playerversion Flash 9.0.124.0
		 */
		protected function onEnterFrame(event:Event):void {
			var  tmpframe:Object = gotoFrame;
			if (gotoFrame is int && currentFrame != gotoFrame){
				return;
			}
			if (gotoFrame is String && currentLabel != gotoFrame) {
				return;
			}
			var totalChildren:int = numChildren;
			for( var i:Number = 0; i < totalChildren; ++i){
				var child:DisplayObject = super_namespace::getChildAt(i);
				if( child == null ) {
					return;
				}
			}
			removeEventListener(Event.ENTER_FRAME, onEnterFrame);
			_isGoto = false;
			populateProxies();
		}
		/**
         * @private (protected)
         *
         * @langversion 3.0
         * @playerversion Flash 9.0.124.0
		 */
		protected function populateProxies():void {
			while (proxies.length > 0){
				var gotoProxyAndRequest:GotoProxyAndRequest = proxies.shift();
				var gotoClip:GotoClip = gotoProxyAndRequest.gotoClip;
				var gotoProxy:GotoProxy = gotoClip.movieClip as GotoProxy;
				var movieClip:MovieClip = callProperty(gotoProxyAndRequest.methodName, gotoProxyAndRequest.index);
				gotoProxy.movieClip = movieClip;
			}
			proxies = null;
			proxies = new Array();
		}
		/**
         * @private
         *
         * @langversion 3.0
         * @playerversion Flash 9.0.124.0
		 */
		super_namespace function getChildAt(index:int):DisplayObject {
			return super_namespace::callProperty("getChildAt", index);
		}
		/**
         * Using this method while a <code>gotoAndStop</code> or <code>gotoAndPlay</code> call is being
         * processed means it will return an instance of the GotoClip class. Properties and method calls 
         * can be made on that class, and when the current instance of the GotoClip class is at the correct 
         * frame those calls will be applied to the display list child referenced in this method.
         * 
         * <p>If a <code>gotoAndStop</code> or <code>gotoAndPlay</code> call is not being processed this method
         * will wrap the GotoClip functionality around any DisplayObjects that are MovieClips.</p>
         *
         * @langversion 3.0
         * @playerversion Flash 9.0.124.0
		 */
		override public function getChildAt(index:int):DisplayObject {
			var displayObject:DisplayObject;
			if(isGoto){
				displayObject = createGotoProxy("getChildAt", index);
			} else {
				displayObject = callProperty("getChildAt", index);
				if (displayObject is MovieClip && !(displayObject is GotoClip)){
					displayObject = new GotoClip(displayObject as MovieClip);
				}
			}
			return displayObject;
		}
		/**
         * Using this method while a <code>gotoAndStop</code> or <code>gotoAndPlay</code> call is being
         * processed means it will return an instance of the GotoClip class. Properties and method calls 
         * can be made on that class, and when the current instance of the GotoClip class is at the correct 
         * frame those calls will be applied to the display list child referenced in this method.
         * 
         * <p>If a <code>gotoAndStop</code> or <code>gotoAndPlay</code> call is not being processed this method
         * will wrap the GotoClip functionality around any DisplayObjects that are MovieClips.</p>
         *
         * @langversion 3.0
         * @playerversion Flash 9.0.124.0
		 */
		override public function getChildByName(name:String):DisplayObject {	
			var displayObject:DisplayObject;	
			if(isGoto){
				displayObject = createGotoProxy("getChildByName", name);
			} else {
				displayObject = callProperty("getChildByName", name);
				if (displayObject is MovieClip && !(displayObject is GotoClip)){
					displayObject = new GotoClip(displayObject as MovieClip);
				}
			}
			return displayObject;
		}		
		/**
         * Starts playing the SWF file at the specified frame. Sets the value of 
         * GotoClip.isGoto to <code>true</code> until the contents at the specified
         * frame are initaliazed and ready.
         * 
         * @param frame to move the playhead to.
         * @param scene containing the frame to move the playhead to.
         *
         * @langversion 3.0
         * @playerversion Flash 9.0.124.0
		 */
		override public function gotoAndPlay(frame:Object, scene:String=null):void {	
			if(isGoto){
				return;
			}
			addEventListener(Event.ENTER_FRAME, onEnterFrame);
			callProperty("gotoAndPlay", frame, scene);
			_isGoto = true;
			gotoFrame = frame;
		}
		/**
         * Brings the playhead to the specified frame of the movie clip and stops it there.
         * Sets the value of GotoClip.isGoto to <code>true</code> until the contents at the 
         * specified frame are initaliazed and ready.
         * 
         * @param frame to move the playhead to.
         * @param scene containing the frame to move the playhead to.
         * 
         * @langversion 3.0
         * @playerversion Flash 9.0.124.0
		 */
		override public function gotoAndStop(frame:Object, scene:String=null):void {
			if(isGoto){
				return;
			}
			addEventListener(Event.ENTER_FRAME, onEnterFrame);
			callProperty("gotoAndStop", frame, scene);
			_isGoto = true;
			gotoFrame = frame;
		}
		/**
         * Sends the playhead to the next frame and stops it.
         *
         * @langversion 3.0
         * @playerversion Flash 9.0.124.0
		 */
		override public function nextFrame():void {
			var nextFrame:int = (movieClip.currentFrame+1>movieClip.totalFrames) ? 0 : movieClip.currentFrame+1;
			gotoAndStop(nextFrame);
		}
		/**
		 * Indicates the DisplayObjectContainer object that contains this display object.
		 * 
         * <p>This method wraps the GotoClip functionality around any parent DisplayObjectContainer 
         * objects that are MovieClip instances.</p>
         *
         * @langversion 3.0
         * @playerversion Flash 9.0.124.0
		 */
		override public function get parent():DisplayObjectContainer {
			var displayObjectContainer:DisplayObjectContainer = getProperty("parent");
			if (displayObjectContainer is MovieClip && !(displayObjectContainer is GotoClip)){
				displayObjectContainer = new GotoClip(displayObjectContainer as MovieClip);
			}
			return displayObjectContainer;
		}
		/**
         * Sends the playhead to the previous frame and stops it.
         *
         * @langversion 3.0
         * @playerversion Flash 9.0.124.0
		 */
		override public function prevFrame():void {
			var prevFrame:int = (movieClip.currentFrame-1 < -1) ? movieClip.totalFrames : movieClip.currentFrame-1;
			gotoAndStop(prevFrame);
		}

	    //------------------------------------------------------------------------------------------------------------
	    //  Complete ActionScript 3.0 Flash Player 9.0 API for flash.display.MovieClip. 
	    //  All methods and properties are overriden and channeled through getProperty, setProperty, or callProperty.
	    //  Functionality remains the same.
	    //------------------------------------------------------------------------------------------------------------

		override public function get accessibilityProperties():AccessibilityProperties {
			return getProperty("accessibilityProperties");
		}
		
		override public function set accessibilityProperties(value:AccessibilityProperties):void {
			setProperty("AccessibilityProperties", value);
		}
		
		override public function get accessibilityImplementation():AccessibilityImplementation {
			return getProperty("accessibilityImplementation");
		}
		
		override public function set accessibilityImplementation(value:AccessibilityImplementation):void {
			setProperty("accessibilityImplementation", value);
		}
		
		override public function get alpha():Number {
			return getProperty("alpha");
		}
		
		override public function set alpha(value:Number):void {
			setProperty("alpha", value);
		}
		
		override public function get blendMode():String {
			return getProperty("blendMode");
		}
		
		override public function set blendMode(value:String):void {
			setProperty("blendMode", value);
		}
		
		override public function get buttonMode():Boolean {
			return getProperty("buttonMode");
		}
		
		override public function set buttonMode(value:Boolean):void {
			setProperty("buttonMode", value);
		}
		
		override public function get cacheAsBitmap():Boolean {
			return getProperty("cacheAsBitmap");
		}
		
		override public function set cacheAsBitmap(value:Boolean):void {
			setProperty("cacheAsBitmap", value);
		}
		
		override public function get contextMenu():ContextMenu {
			return getProperty("contextMenu");
		}
		
		override public function set contextMenu(value:ContextMenu):void {
			setProperty("contextMenu", value);
		}
		
		override public function get currentFrame():int {
			return getProperty("currentFrame");
		}
		
		override public function get currentLabel():String {
			return getProperty("currentLabel");
		}
		
		override public function get currentLabels():Array {
			return getProperty("currentLabels");
		}
		
		override public function get currentScene():Scene {
			return getProperty("currentScene");
		}
		
		override public function get doubleClickEnabled():Boolean {
			return getProperty("doubleClickEnabled");
		}
		
		override public function set doubleClickEnabled(value:Boolean):void {
			setProperty("doubleClickEnabled", value);
		}
		
		override public function get dropTarget():DisplayObject {
			return getProperty("dropTarget");
		}

		override public function get enabled():Boolean {
			return getProperty("enabled");
		}
		
		override public function set enabled(value:Boolean):void {
			setProperty("enabled", value);
		}
		
		override public function get filters():Array {
			return getProperty("filters");
		}
		
		override public function set filters(value:Array):void {
			setProperty("filters", value);
		}
		
		override public function get focusRect():Object {
			return getProperty("focusRect");
		}
		
		override public function set focusRect(value:Object):void {
			setProperty("focusRect", value);
		}
		
		override public function get framesLoaded():int {
			return getProperty("framesLoaded");
		}
		
		override public function get graphics():Graphics {
			return getProperty("graphics");
		}
		
		override public function get height():Number {
			return getProperty("height");
		}
		
		override public function set height(value:Number):void {
			setProperty("height", value);
		}
		
		override public function get hitArea():Sprite {
			return getProperty("hitArea");
		}
		
		override public function set hitArea(value:Sprite):void {
			setProperty("hitArea", value);
		}
		
		override public function get loaderInfo():LoaderInfo {
			return getProperty("loaderInfo");
		}
		
		override public function get mask():DisplayObject {
			return getProperty("mask");
		}
		
		override public function set mask(value:DisplayObject):void {
			setProperty("mask", value);
		}
		
		override public function get mouseChildren():Boolean {
			return getProperty("mouseChildren");
		}
		
		override public function set mouseChildren(value:Boolean):void {
			setProperty("mouseChildren", value);
		}
		
		override public function get mouseEnabled():Boolean {
			return getProperty("mouseEnabled");
		}
		
		override public function set mouseEnabled(value:Boolean):void {
			setProperty("mouseEnabled", value);
		}
		
		override public function get mouseX():Number {
			return getProperty("mouseX");
		}
		
		override public function get mouseY():Number {
			return getProperty("mouseY");
		}
		
		override public function get name():String {
			return getProperty("name");
		}
		
		override public function set name(value:String):void {
			setProperty("name", value);
		}
		
		override public function get numChildren():int {
			return getProperty("numChildren");
		}
		
		override public function get opaqueBackground():Object {
			return getProperty("opaqueBackground");
		}
		
		override public function set opaqueBackground(value:Object):void {
			setProperty("opaqueBackground", value);
		}
		
		override public function get root():DisplayObject {
			return getProperty("root");
		}
		
		override public function get rotation():Number {
			return getProperty("rotation");
		}
		
		override public function set rotation(value:Number):void {
			setProperty("rotation", value);
		}
		
		override public function get scale9Grid():Rectangle {
			return getProperty("scale9Grid");
		}
		
		override public function set scale9Grid(value:Rectangle):void {
			setProperty("scale9Grid", value);
		}
		
		override public function get scaleX():Number {
			return getProperty("scaleX");
		}
		
		override public function set scaleX(value:Number):void {
			setProperty("scaleX", value);
		}		
		
		override public function get scaleY():Number {
			return getProperty("scaleY");
		}
		
		override public function set scaleY(value:Number):void {
			setProperty("scaleY", value);
		}
		
		override public function get scenes():Array {
			return getProperty("scenes");
		}
		
		override public function get scrollRect():Rectangle {
			return getProperty("scrollRect");
		}
		
		override public function set scrollRect(value:Rectangle):void {
			setProperty("scrollRect", value);
		}	
		
		override public function get soundTransform():SoundTransform {
			return getProperty("soundTransform");
		}
		
		override public function set soundTransform(value:SoundTransform):void {
			setProperty("soundTransform", value);
		}
		
		override public function get stage():Stage {
			return getProperty("stage");
		}
		
		override public function get tabChildren():Boolean {
			return getProperty("tabChildren");
		}
		
		override public function set tabChildren(value:Boolean):void {
			setProperty("tabChildren", value);
		}	
		
		override public function get tabEnabled():Boolean {
			return getProperty("tabEnabled");
		}
		
		override public function set tabEnabled(value:Boolean):void {
			setProperty("tabEnabled", value);
		}
		
		override public function get tabIndex():int {
			return getProperty("tabIndex");
		}
		
		override public function set tabIndex(value:int):void {
			setProperty("tabIndex", value);
		}
		
		override public function get textSnapshot():TextSnapshot {
			return getProperty("textSnapshot");
		}
		
		override public function get totalFrames():int {
			return getProperty("totalFrames");
		}
		
		override public function get trackAsMenu():Boolean {
			return getProperty("trackAsMenu");
		}
		
		override public function set trackAsMenu(value:Boolean):void {
			setProperty("trackAsMenu", value);
		}
		
		override public function get transform():Transform {
			return getProperty("transform");
		}
		
		override public function set transform(value:Transform):void {
			setProperty("transform", value);
		}
		
		override public function get useHandCursor():Boolean {
			return getProperty("useHandCursor");
		}
		
		override public function set useHandCursor(value:Boolean):void {
			setProperty("useHandCursor", value);
		}
		
		override public function get visible():Boolean {
			return getProperty("visible");
		}
		
		override public function set visible(value:Boolean):void {
			setProperty("visible", value);
		}
		
		override public function get width():Number {
			return getProperty("width");
		}
		
		override public function set width(value:Number):void {
			setProperty("width", value);
		}	
		
		override public function get x():Number {
			return getProperty("x");
		}
		
		override public function set x(value:Number):void {
			setProperty("x", value);
		}		
		
		override public function get y():Number {
			return getProperty("y");
		}
		
		override public function set y(value:Number):void {
			setProperty("y", value);
		}

		override public function addChild(child:DisplayObject):DisplayObject {
			return callProperty("addChild", child);
		}
		
		override public function addChildAt(child:DisplayObject, index:int):DisplayObject {
			return callProperty("addChildAt", child, index);
		}
		
		override public function addEventListener(type:String, listener:Function, useCapture:Boolean=false, priority:int=0, useWeakReference:Boolean=false):void {
			callProperty("addEventListener", type, listener, useCapture, priority, useWeakReference);
		}
		
		override public function areInaccessibleObjectsUnderPoint(point:Point):Boolean {
			return callProperty("areInaccessibleObjectsUnderPoint", point);
		}
		
		override public function contains(child:DisplayObject):Boolean {
			return callProperty("contains", child);
		}
		
		override public function dispatchEvent(event:Event):Boolean {
			return callProperty("dispatchEvent", event);
		}
		
		override public function getBounds(targetCoordinateSpace:DisplayObject):Rectangle {
			return callProperty("getBounds", targetCoordinateSpace);
		}
		
		override public function getChildIndex(child:DisplayObject):int {
			return callProperty("getChildIndex", child);
		}
		
		override public function getObjectsUnderPoint(point:Point):Array {
			return callProperty("getObjectsUnderPoint", point);
		}
		
		override public function getRect(targetCoordinateSpace:DisplayObject):Rectangle {
			return callProperty("getRect", targetCoordinateSpace);
		}
		
		override public function globalToLocal(point:Point):Point {
			return callProperty("globalToLocal", point);
		}
		
		override public function hasEventListener(type:String):Boolean {
			return callProperty("hasEventListener", type);
		}
		
		override public function hitTestObject(obj:DisplayObject):Boolean {
			return callProperty("hitTestObject", obj);
		}
		
		override public function hitTestPoint(x:Number, y:Number, shapeFlag:Boolean=false):Boolean {
			return callProperty("hitTestPoint", x, y, shapeFlag);
		}
		
		override public function localToGlobal(point:Point):Point {
			return callProperty("localToGlobal", point);
		}
		
		override public function nextScene():void {
			callProperty("nextScene");
		}
		
		override public function play():void {
			callProperty("play");
		}
		
		override public function prevScene():void {
			callProperty("prevScene");
		}
		
		override public function removeChild(child:DisplayObject):DisplayObject {
			return callProperty("removeChild", child);
		}
		
		override public function removeChildAt(index:int):DisplayObject {
			return callProperty("removeChildAt", index);
		}

		override public function removeEventListener(type:String, listener:Function, useCapture:Boolean=false):void {
			callProperty("removeEventListener", type, listener, useCapture);
		}
		
		override public function setChildIndex(child:DisplayObject, index:int):void {
			callProperty("setChildIndex", child, index);
		}
		
		override public function startDrag(lockCenter:Boolean=false, bounds:Rectangle=null):void {
			callProperty("startDrag", lockCenter, bounds);
		}
		
		override public function stop():void {
			callProperty("stop");
		}
		
		override public function stopDrag():void {
			callProperty("stopDrag");
		}
		
		override public function swapChildren(child1:DisplayObject, child2:DisplayObject):void {
			callProperty("swapChildren", child1, child2);
		}
		
		override public function swapChildrenAt(index1:int, index2:int):void {
			callProperty("swapChildrenAt", index1, index2);
		}
		
		override public function toString():String {
			return callProperty("toString");
		}

		override public function willTrigger(type:String):Boolean {
			return callProperty("willTrigger", type);
		}
	}
}
/**
 * Internal helper class that contains an instance of the GotoProxy class
 * and the methodName and index parameter made to retrieve the GotoProxy class.
 * @private
 */
import ca.johannes.display.GotoClip;
internal class GotoProxyAndRequest
{
	private var _gotoClip:GotoClip;
	private var _methodName:String;
	private var _index:*;
	
	public function GotoProxyAndRequest(gotoClip:GotoClip, methodName:String, index:*){
		_gotoClip = gotoClip;
		_methodName = methodName;
		_index = index;
	}
	public function get gotoClip():GotoClip {
		return _gotoClip;
	}
	public function get methodName():String {
		return _methodName;
	}
	public function get index():* {
		return _index;
	}

}